package com.zby.ss.core;

import com.zby.ss.core.builder.FactoryBuilder;
import com.zby.ss.core.vo.XmlBeanProperty;
import com.zby.ss.core.vo.XmlConfigBean;
import com.zby.ss.util.CollectionUtil;
import org.apache.commons.lang3.StringUtils;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * Created By zby on 22:56 2019/3/4
 */

public class LoadConfig {

    private static Logger logger = LoggerFactory.getLogger(LoadConfig.class.getName());

    private static Map<String, Map<String, XmlConfigBean>> allXmls = null;

    private static LoadConfig config = null;

    private LoadConfig() {
    }

    public Map<String, Map<String, XmlConfigBean>> getAllXmls() {
        return allXmls;
    }

    /**
     * Created By zby on 22:57 2019/3/4
     * 加载配置文件
     */
    public static LoadConfig loadXmlConFig(String dirPath) {
        if (StringUtils.isEmpty(dirPath)){
            throw new RuntimeException("路径不存在");
        }
        if (null == config) {
            File dir = new File(dirPath);
            List<File> files = FactoryBuilder.createFileFactory().listFile(dir);
            if (CollectionUtil.isEmpty(files)) {
                throw new RuntimeException("没有配置文件files=" + files);
            }
            allXmls = new HashMap<>();
            SAXBuilder saxBuilder = new SAXBuilder();
            Document document = null;
            for (File file : files) {
                try {
                    Map<String, XmlConfigBean> beanMaps = new HashMap<>();
                    //创建配置文件
                    String configFileName = file.getName();
                    document = saxBuilder.build(file);
                    Element rootEle = document.getRootElement();
                    List beans = rootEle.getChildren("bean");
                    if (CollectionUtil.isNotEmpty(beans)) {
                        int i = 0;
                        for (Iterator beanIterator = beans.iterator(); beanIterator.hasNext(); i++) {
                            Element bean = (Element) beanIterator.next();
                            XmlConfigBean configBean = new XmlConfigBean();
                            configBean.setId(attributeToConfigBeanProps(file, i, bean, "id"));
                            configBean.setClazz(attributeToConfigBeanProps(file, i, bean, "class"));
                            configBean.setAutowire(attributeToConfigBeanProps(file, i, bean, "autowire"));
                            configBean.setConfigFileName(configFileName);
                            List properties = bean.getChildren();
                            Set<XmlBeanProperty> beanProperties = new LinkedHashSet<>();
                            if (CollectionUtil.isNotEmpty(properties)) {
                                int j = 0;
                                for (Iterator propertyIterator = properties.iterator(); propertyIterator.hasNext(); j++) {
                                    Element property = (Element) propertyIterator.next();
                                    XmlBeanProperty beanProperty = new XmlBeanProperty();
                                    beanProperty.setName(attributeToBeanProperty(file, i, j, property, "name"));
                                    beanProperty.setRef(attributeToBeanProperty(file, i, j, property, "ref"));
                                    beanProperty.setValue(attributeToBeanProperty(file, i, j, property, "value"));
                                    beanProperties.add(beanProperty);
                                }
                                configBean.setProperties(beanProperties);
                            }
                            beanMaps.put(configBean.getId(), configBean);
                        }
                    }
                    allXmls.put(configFileName, beanMaps);
                } catch (JDOMException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return new LoadConfig();
        }
        return config;
    }


    /**
     * Created By zby on 22:48 2019/2/14
     *
     * @param file 文件
     * @param i    第几个bean标签
     * @param bean 表示bean标签
     * @param attr 属性名称
     */
    private static String attributeToConfigBeanProps(File file, int i, Element bean, String attr) {
        Attribute attribute = bean.getAttribute(attr);
        if (null == attribute) {
            if (attr.equals("autowire")) {
                return null;
            }
            String info = "配置文件" + file.getName() + "的第 " + i + "bean的属性缺少" + attr + "属性";
            logger.error(info);
            throw new RuntimeException(info);
        }
        return attribute.getValue();
    }

    /**
     * Created By zby on 22:48 2019/2/14
     *
     * @param file 文件
     * @param i    第几个bean标签
     * @param bean 表示bean标签
     * @param attr 属性名称
     */
    private static String attributeToBeanProperty(File file, int i, int j, Element bean, String attr) {
        Attribute attribute = bean.getAttribute(attr);
        if (null == attribute) {
            return null;
        }
        return attribute.getValue();
    }

}